干货 | Rheos SQL: 高效易用的实时流式SQL处理平台
更多干货请关注“eBay技术荟”公众号
导读
本文介绍了Rheos SQL这一实时流式SQL处理平台在设计和实现中的细节。用户可以使用SQL语言,在Rheos SQL平台方便地编写、提交和维护实时流处理业务,节省开发和运维成本。
一、动机
01
实时即未来
自2015年“streaming 101: the world beyond batch”[1] 发表以来,已经过去了将近5年。现在,越来越多的人相信,批处理是流式处理的特殊情况,基于流式处理的实时数据分析才是未来发展的方向。
与传统批处理相比,流式处理的优势有以下几点:
输出结果的延时更低:从之前的小时级和天级,降为分钟级和秒级。 模型更契合:很多大规模数据,比如访问网站的用户行为数据,生成的模式是源源不断的,流式处理模型更符合数据本身生成的模式。
流处理的框架,在开源和商用领域也取得了很好的发展[2],如今更加成熟和稳定,足够在生产环境广泛使用。其中Apache Flink[3]的模型定义和机制设计比较符合公司里的业务场景,很多用户都在其上建立自己的应用程序。
02
简单强大的SQL语言
SQL是数据分析人员最熟悉的语言。相对于传统运行在数据库和批处理中的SQL,流式SQL有以下特点:
面相无界的流式数据源。与流式处理一样,流式SQL所针对的数据源也是无界流,没有起始,也没有终点。 依照流式处理的定义,增加相应的关键字和语义扩展。流式处理常见的概念有:窗口(Window),触发器(Trigger),水位线(Watermark)等。
节省开发成本:作为简单易用的高级语言,SQL的描述能力更强,同样的逻辑开发起来更快速。 节省维护成本:修改清晰易懂的SQL脚本,比修改复杂的代码逻辑更容易。 更好的透明性:对底层细节的隐藏,使得用SQL语言表达的逻辑可以规避掉一部分底层实现变动带来的迁移。
当然,由于抽象层次更高,SQL可能只能覆盖80%的用户场景,所以,流处理框架通过支持User Defined Function(UDF)和Complex Event Processing(CEP)来满足更高级别用户的需求。
03
拥抱开源社区的同时弥补缺陷
SQL语法和语义本身不够全面:真正的线上业务场景复杂,使用到的外围系统众多,开源产品不能直接全部满足。举个例子,公司内部有一种将RESTful服务作为维表,与源数据进行JOIN的需求,但在当前的开源产品中,并不能找到原生的支持。
易用性:开源的SQL处理引擎是作为框架形式提供的,用户需要自己管理SQL脚本、UDF,并考虑如何与底层的执行引擎做集成。
稳定性:开源产品的接口变动是不受单个公司控制的,业务团队都希望只花力气在业务逻辑的开发,而不是不断地因平台层的接口变动而修改逻辑。
监控与报警:开源产品通常是提供基础监控的,但是要在生产环境广泛使用,且往往需要与公司内部的监控报警系统集成。在开源基础上,也需要依照实际情况添加更多的监控指标。
二、功能
01
SQL语义与语法
当前支持的语法模块如下表所示:
(点击可查看高清大图)
02
与外部资源对接模块
三、架构
(点击可查看高清大图)
如上图所示,在总体架构上,Rheos SQL分为三层:核心服务层(Core Service Layer),SQL开发工具包层(SQL SDK Layer)以及基础服务层(Infrastructure Layer)。
01
核心服务层(Core Service Layer)
该层主要负责管理面相用户的SQL资源,是用户接触的主要接口。
以RESTful服务的形式,将Rheos SQL的核心资源暴露给用户,核心资源包括:
SQL脚本(SQL Script):用户所编写的SQL语句,用以描述业务逻辑,属性包括存贮的位置等。 UDF包(UDF Package):用户的自定义函数包,属性包括存储的位置,包中支持的函数等。 SQL作业(SQL Job):SQL运行时的抽象,是SQL脚本的实例化之后,在集群中运行的实例,属性包括关联的SQL脚本,启动参数等。
02
SQL开发工具包层(SQL SDK Layer)
该层负责在开源流式SQL引擎上增强扩展,支持更丰富的语义和语法。
核心SQL模块(Core SQL Modules):负责SQL的解析,优化和执行计划生成。
与外部资源对接模块(Connects):加载和拉取存储在外部依赖中的数据,比如Kafa-Connect会维护Kafka的Consumer,从Kafka消费数据,并交给流处理引擎。
用户自定义函数模块(UDF):支持自定义函数和组件,比如对源数据的自定义解析函数。
执行提供模块(Executor Provider):抽象层,隐藏底层实现细节,保证对外编程接口稳定。
该层的设计可以帮助我们在不影响用户的同时,灵活切换底层基础服务的实现。比如,Rheos SQL可以内部升级FLINK的版本,或者使用其他流处理框架实现流处理的功能,而用户对接的则一直是Rheos SQL定义的语法与编程接口。
03
基础服务层(Infrastructure Layer)
该层负责运行时基础设施的提供与维护。在公司内部,所有集群都运行在K8S平台,并有流平台团队提供了流处理基础设施的管理。
当前,Rheos SQL选用的流处理框架是Apache Flink,流平台团队管理了Flink集群的创建与维护,并支持资源额度管理、基础监控暴露收集等。
四、用户体验
Git:作为公司广泛使用的代码库管理工具,Git本身就提供强大的版本控制和历史信息追踪,推荐部署到生产环境的Rheos SQL应用都采用这种源代码库。
DB:直接将SQL源脚本提交到Rheos SQL系统,落库。适用于跑DEMO,或者功能性验证阶段。
如果是比较高级的用户,需要编写UDF或者在SQL工具包的基础上定制功能,可以在本地编码结束后,上传到远程的存储。流平台团队提供了MAVEN插件,可以在IDE中方便地完成上传。在实现时,我们使用的对象存储是Swift[7]。
除此之外,用户需要将SQL脚本和自定义的包在Rheos SQL的系统中注册,完成源信息的提交(Metadata Onboard)。为了尽快找到程序中的bug,验证逻辑和配置细节,Rheos SQL平台提供了线上验证和配置的功能。一切就绪后,可以在Rheos SQL平台提交作业。Rheos SQL会将这个SQL作业,转化成底层流平台具体实现的作业。在当前实现中,Rheos SQL作业会被注册成Flink的作业,存放到流平台上。在运行时,Rheos SQL的工具包会根据用户注册的信息,动态拉取SQL脚本的源代码,并加载用户自定义的扩展包,进行解析、优化并在流框架上执行用户逻辑。作业运行起来后,可以通过Rheos SQL的门户网站操作和监控。
五、与维表的JOIN
01
用例
在现有的业务场景中,有很多使用源表数据与外部存储JOIN的用例。
上图是实际应用的一个例子,输出与用户购买行为相关的统计信息。SQL作业的数据源是存放在Kafka中的用户交易数据。
处理的第一步,是将源表与一张RESTful形式的维表根据user域做JOIN,构造出cguid_view临时表。
处理的第二步,是将cguid_view临时表,与存放在Cassandra中的一张维表,根据user和itemId域做JOIN,输出event_view临时表。
处理的第三步,是在event_view临时表上做聚合,将最终的结果输出到Cassandra。02
实现细节
为了提升性能,在实现维表JOIN时,Rheos SQL重点做了以下两方面的工作:
LRU缓存:为了减少与外部存储的频繁交互,在内存中会默认开启LRU的缓存。同样的KEY,在缓存失效前,会优先从缓存中返回。新的KEY在首次取回之后,也会加入到缓存中。 异步查询:为了在等待外部存储返回结果前,避免同步等待IO,Rheos SQL使用了FLINK的Async API实现异步查询。Rheos SQL中的所有维表实现,都继承自一个支持异步的抽象类,子类实现数据拿取的业务逻辑,并将结果以Future的形式返回给父类。父类负责对结果的最终处理。
六、Debug和监控
01
本地测试框架
SQL开放工具集中,提供了一个本地测试框架,具体功能为:
以文件的形式,定义SQL作业的输入和输出。
本地启动所有的外部依赖模块,将输入写到源和对应的维表。 运行SQL的处理逻辑,并将输出写入到目标存储和文件。 比较目标输出是否与用户一开始定义的一致,并返回比较结果。
在这个测试框架的帮助下,用户可以本地完成SQL脚本的开发和测试工作,并初步验证逻辑的正确性,及时对bug做好修正。
02
SQL逻辑图
(点击可查看高清大图)
上图是一个实际应用中的例子。源表和维表在第一次JOIN之后,将聚合的结果写入到了TEMP_VIEW,然后从临时表中选取了部分数据输出到目标表。
用户通过逻辑执行图,可以验证逻辑是否符合预期,在将SQL作业真正运行前,发现问题并修正。03
线上SQL作业的监控
除去Flink本身提供的监控指标之外,Rheos SQL还提供了很多从SQL表级别暴露的信息。根据表类型的不同,部分指标详情如下:
源表:消费者尚未读取的数据量(Consumer Lag),读入数据条数,读入数据量等。
维表:接受数据条数,读取外部数据响应时间,与外部系统建立的连接数等。 目标表:输出的数据条数,写入外部系统失败的条数等。
总结与展望
Rheos SQL平台在开源流式SQL处理框架的基础上,提供了丰富的语义与扩展。用户可以在Rheos SQL平台上,方便地开发、调试、监控SQL作业,节省流式作业的开发,维护成本。接下来,Rheos SQL在进一步满足用户需求的同时,将会在资源管理、动态扩容以及CEP语义支持等方面,投入更多的努力。
参考文献
[7] https://wiki.openstack.org/wiki/Swift
分享 | eBay流量管理之负载均衡及应用交付
👇点击阅读原文,一键投递